package com.game.server.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.game.majiang.algorithm.PaperCard;
import com.game.majiang.config.DataManager;
import com.game.majiang.config.LogManager;
import com.game.majiang.logic.*;
import com.game.majiang.logic.chexuan.ChexuanTableStatus;
import com.game.majiang.vo.GrateCardsVo;
import com.game.majiang.vo.UserVo;
import com.game.server.GameServer;
import com.game.server.system.AbstractClient;
import com.game.server.system.AbstractRoom;
import com.robot.RobotClient;
import com.robot.RobotManager;
import lombok.Getter;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@WebService
public class WebServer {

  //	public static void init() {
  //		InetAddress addr ;
  //		try {
  //			addr = InetAddress.getLocalHost();
  //			String ip=addr.getHostAddress().toString();//获得本机IP
  //			Endpoint.publish(MessageFormat.format(WebConfig.URL, ip), new WebServer());
  //			LogManager.getInstance().Log("启动webservice:ip="+ip);
  //		} catch (UnknownHostException e) {
  //			LogManager.getInstance().Log("启动webservice失败");
  //			e.printStackTrace();
  //		}
  //	}

  /**
   * 指定玩家id对应的下局卡牌
   */
  @Getter
  private static final Map<Integer, ArrayList<PaperCard>> zbMap = new ConcurrentHashMap<>();


  private String[] parameterKey = {
      "AndroidDownloadLink",
      "IosDownloadLink",
      "AndroidDownloadCode",
      "IosDownloadCode",
      "gameannouncement",
      "rollingbulletin",
      "lowestCreateClubCard",
      "zjurl",
      "kefuweixinhao"
  };

  public static void init() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    InetAddress addr;
    try {
    //  addr = InetAddress.getLocalHost();
      addr = InetAddress.getByName("0.0.0.0"); // 获得本机IP
      String ip = addr.getHostAddress();// 获得本机IP
      LogManager.getInstance().Log("web监听WebConfig.URL:" + WebConfig.URL);
      Endpoint.publish(MessageFormat.format(WebConfig.URL, ip), new WebServer());
    } catch (UnknownHostException e) {
      e.printStackTrace();
    }
  }

  @WebMethod
  public boolean closeServer() {
    LogManager.getInstance().Log("服务关闭");
    LogicServer server = LogicServer.getInstance();
    Collection<AbstractClient> c = server.getClients();
    for (AbstractClient ab : c) {
      LogicClient client2 = (LogicClient) ab;
      if (client2.getPlayer() != null) {
        LogicPlayer player = (LogicPlayer) client2.getPlayer();
        player.setReady(false);
      }
      client2.Close();
    }
    return GameServer.getInstance().close();
  }

  @WebMethod
  public boolean openServer() {

    boolean open = false;
    LogicServer.getInstance().init();
    GameServer game = new GameServer();

    try {
      game.getInstance().bind(game.getInstance().getPort());
      open = true;
      game.getInstance().finish();
      LogManager.getInstance().Log("服务开启");
    } catch (Exception e) {
      open = false;
      e.printStackTrace();
    }

    return open;
  }


  @WebMethod
  public String findOnlineUsers() {
    JSONArray userids = new JSONArray();
    Collection<AbstractClient> clients = LogicServer.getInstance().getClients();
    for (AbstractClient client : clients) {
      LogicClient cl = (LogicClient) client;
      if (cl != null) {
        userids.add(cl.getUserId() + "");
      }
    }
    return userids.toString();
  }

  /**
   * 添加货币
   *
   * @param uid
   * @param money
   */
  @WebMethod
  public long addMoney(int uid, long money) {
    LogManager.getInstance().Log("添加货币: uid=" + uid + ", money=" + money);
    LogicClient client = (LogicClient) LogicServer.getInstance().getClient(uid);
    if (client != null) {
      // 添加积分
      client.getVo().AddIntegral((int) money);
      client.getVo().updateGlod(client.getUserId(), client.getVo().getIntegral(), 3);
      return client.getVo().getIntegral();
    }
    LogManager.getInstance().Log("用户不存在: uid=" + uid);
    return -1;
  }

  /**
   * 设置测试权限
   *
   * @param uid
   * @param money
   */
  @WebMethod
  public long setTest(int uid, long money) {
    LogManager.getInstance().Log("设置测试权限: uid=" + uid + ", 权限=" + money);

    LogicClient client = (LogicClient) LogicServer.getInstance().getClient(uid);
    if (client != null) {
      // 添加积分
      client.getVo().SetTest((int) money);

      return client.getVo().getIntegral();
    }
    LogManager.getInstance().Log("用户不存在: uid=" + uid);
    return -1;
  }

  /**
   * 添加下局卡牌
   *
   * @param uid
   * @param kaPaiStr "10-1,11-1,12-1,13-1"
   * @return
   */
  @WebMethod
  public String setPlayerHandK(int uid, String kaPaiStr) {
    LogManager.getInstance().Log("添加玩家下局卡牌: uid=" + uid + ", kaPaiStr=" + kaPaiStr);
    try {
      LogicClient client = (LogicClient) LogicServer.getInstance().getClient(uid);
      if (client != null) {
        ArrayList<PaperCard> list = new ArrayList<>();
        String[] arr = kaPaiStr.split(",");
        for (String s : arr) {
          String[] arr1 = s.split("-");
          PaperCard p = new PaperCard();
          p.setNum(Integer.parseInt(arr1[0]));
          p.setType(Integer.parseInt(arr1[1]));
          list.add(p);
        }
        zbMap.put(uid, list);
        return "ok";
      } else {
        return "fail:玩家不存在或不在线";
      }
    } catch (Exception e) {
      e.printStackTrace();
      LogManager.getInstance().Log("添加玩家下局卡牌-异常：" + e.getMessage());
    }
    return "fail";
  }

  public static void main(String[] args) {
    List<PaperCard> list = new ArrayList<>();
    String str = "10-1,11-1,12-1,13-1";
    String[] arr = str.split(",");
    for (String s : arr) {
      String[] arr1 = s.split("-");
      PaperCard p = new PaperCard();
      p.setNum(Integer.parseInt(arr1[0]));
      p.setType(Integer.parseInt(arr1[1]));
      list.add(p);
    }
    System.out.println(JSON.toJSONString(list));
  }

  @WebMethod
  public boolean getServerStatus() {

    GameServer game = new GameServer();

    LogManager.getInstance().Log("服务状态:" + game.getInstance().isRunning());
    return game.getInstance().isRunning();
  }

  /**
   * 修改参数表
   */
  @WebMethod
  public void updateParameter(String key, String value) {
    if (DataManager.getInstance().systemValue(key) != null) {
      DataManager.getInstance().getSys_parameter().put(key, value);
      for (int i = 0; i < parameterKey.length; i++) {
        if (parameterKey[i].equals(key)) {
          Collection<AbstractClient> clients = LogicServer.getInstance().getClients();
          for (AbstractClient abstractClient : clients) {
            UserVo.getuserinfo((LogicClient) abstractClient);
          }
          break;
        }

      }

    }
  }

  /**
   * 查询机器人
   * @return
   */
  @WebMethod
  public String queryRobotList() {
    return JSON.toJSONString(RobotManager.getInstance().obtainAllRobotsInfo());
  }

  /**
   * 向房间添加机器人
   * @param tableId
   */
  @WebMethod
  public boolean addRobotIntoRoom(int tableId, int robotNum, int grateCardsProbability) {
    LogManager.getInstance().Log("向房间添加机器人: tableId=" + tableId + ", robotNum=" + robotNum);
    if(robotNum == 0) {
      return false;
    }
    LogicServer server = LogicServer.getInstance();
    Optional<LogicTable> table = server.getRooms().stream()
        .filter(r -> r.getTable(tableId) != null)
        .map(r -> (LogicTable) r.getTable(tableId))
        .findFirst();
    if(!table.isPresent()) {
      LogManager.getInstance().Log("游戏桌不存在");
      return false;
    }
    if(!(table.get().getChexuanStatus() == ChexuanTableStatus.WAIT)) {
      LogManager.getInstance().Log("游戏桌状态不是等待状态");
      return false;
    }
    if(RobotManager.getInstance().robotsCount() < robotNum) {
      LogManager.getInstance().Log("机器人数量不足");
      return false;
    }
    if(grateCardsProbability < 0 || grateCardsProbability > 100) {
      grateCardsProbability = 0;
    }
    for(int i = 0; i < robotNum; i += 1) {
      Optional<RobotClient> rc = Optional.ofNullable(RobotManager.getInstance().createRobot(table.get()));
      if(!rc.isPresent()) {
        LogManager.getInstance().Log("机器人创建失败，没有空余的机器人");
        return false;
      }
      rc.get().setGrateCardsProbability(grateCardsProbability);
      if(Optional.ofNullable(rc.get().getClient()).isPresent() &&
          Optional.ofNullable(server.getClient(rc.get().getClient().getUserId())).isPresent()) {
        rc.get().getClient().setTableid(table.get().getID());
        rc.get().getClient().setRoomid(1);
        table.get().enterWatchPlayer(rc.get().getClient());
        RobotManager.getInstance().addRobot(rc.get());
        LogManager.getInstance().Log("机器人 " + rc.get().getClient().getUserId() + " 创建成功");
      }
    }
    return true;
  }

  /**
   * 添加好牌牌型
   * @return 添加结果
   */
  @WebMethod
  public boolean addGrateCardGroup(int x1, int x2, int x3, int x4) {
    List<Integer> cards = Arrays.asList(x1, x2, x3, x4);
    List<Integer> typeList = new ArrayList<>();
    List<Integer> numList = new ArrayList<>();
    for(int i = 0; i < 4; i += 1) {
      int card = cards.get(i);
      int num = card % 100;
      if(num < 1 || num > 15) {
        LogManager.getInstance().Log("添加牌组失败：牌型错误：" + card);
        return false;
      }
      int type = card / 100;
      typeList.add(type);
      numList.add(num);
    }
    LogManager.getInstance().Log("添加牌组：" + typeList + "\n" + numList);
    return GrateCardsVo.getInstance().addGrateCards(typeList, numList);
  }

  /**
   * 查询所有的牌型组合
   * @return 牌型组合
   */
  @WebMethod
  public String queryGrateCardGroup() {
    return JSON.toJSONString(GrateCardsVo.getInstance().queryGrateCards());
  }

  /**
   * 删除牌型组合
   * @return
   */
  @WebMethod
  public boolean deleteGrateCardGroup(int id) {
    return GrateCardsVo.getInstance().removeGrateCards(id);
  }

  // @WebMethod
  // public String queryTables() {
  //   LogicServer server = LogicServer.getInstance();
  //   // Room id is always 1;
  //   LogicRoom room = (LogicRoom) server.getRoom(1);
  //   List<LogicTable> tables = room.getTables().stream().map(t -> (LogicTable) t)
  //       .collect(Collectors.toList());
  //   return JSON.toJSONString(tables);
  // }

  @WebMethod
  public String queryTables(int id) {
    LogManager.getInstance().Log("查找ID为 " + id + "的桌子");
    LogicServer server = LogicServer.getInstance();
    // Room id is always 1;
    LogicRoom room = (LogicRoom) server.getRoom(1);
    List<Map<String, Object>> res = room.getTables().stream().filter(t -> id == 0 || t.getID() == id)
        .map(t -> {
          Map<String, Object> map = new HashMap<>();
          LogicTable lt = (LogicTable) t;
          map.put("room_id", lt.getID());
          map.put("club_id", lt.getClubid());
          map.put("banker_id", lt.getCreate().getBankerid());
          map.put("room_name", lt.getCreate().getRoomname());
          map.put("difen", lt.getCreate().getDifen());
          map.put("current_player_num", lt.getPlayers().stream().count());
          return map;
        }).collect(Collectors.toList());
    return JSON.toJSONString(Collections.singletonMap("list", res));
  }

}
